package com.gm.corejava.book2;

import javax.crypto.*;
import java.io.*;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

/**
 * Created with IntelliJ IDEA.
 * User: camark@sina.cn
 * Date: 13-12-30
 * Time: 下午1:10
 */
public class ACETest {
    public static void main(String[] args) throws NoSuchAlgorithmException, IOException, ClassNotFoundException, NoSuchPaddingException, InvalidKeyException,ShortBufferException,IllegalBlockSizeException,BadPaddingException {
        if(args[0].equals("-secretkey")){
            KeyGenerator keyGenerator=KeyGenerator.getInstance("AES");
            SecureRandom secureRandom=new SecureRandom();
            keyGenerator.init(secureRandom);
            SecretKey secretKey=keyGenerator.generateKey();
            ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream(args[1]));
            objectOutputStream.writeObject(secretKey);
            objectOutputStream.close();
        }
        else
        {
            int mode;
            if(args[0].equals("encrypt")){
                mode= Cipher.ENCRYPT_MODE;
            }
            else{
                mode=Cipher.DECRYPT_MODE;
            }

            ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream(args[3]));
            Key key=(Key)objectInputStream.readObject();
            objectInputStream.close();

            InputStream inputStream=new FileInputStream(args[1]);
            OutputStream outputStream=new FileOutputStream(args[2]);
            Cipher cipher=Cipher.getInstance("AES");
            cipher.init(mode,key);

            crypt(inputStream,outputStream,cipher);
            inputStream.close();
            outputStream.close();
        }
    }

    private static void crypt(InputStream inputStream, OutputStream outputStream, Cipher cipher) throws IOException,ShortBufferException,IllegalBlockSizeException,BadPaddingException {
        int blockSize=cipher.getBlockSize();
        int outputSize=cipher.getOutputSize(blockSize);

        byte[] inBytes=new byte[blockSize];
        byte[] outBytes=new byte[outputSize];

        int iLength=0;
        boolean bMore=true;

        while(bMore){
            iLength=inputStream.read(inBytes);
            if(iLength==blockSize){
                int outLength=cipher.update(inBytes,0,blockSize,outBytes);
                outputStream.write(outBytes,0,outLength);
            }
            else
                bMore=false;
        }

        if(iLength>0) outBytes=cipher.doFinal(inBytes,0,iLength);
        else
            outBytes=cipher.doFinal();

        outputStream.write(outBytes);
    }


}
